﻿using System;
using System.IO;
using System.Drawing;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Web;

namespace Project.Tool
{

	/// <summary>
	/// 操作图片
	/// </summary>
	public class Img
	{
		/// <summary>
		/// 压缩图片
		/// </summary>
		public class ComPress
		{
			/// <summary>
			/// 图片路径
			/// </summary>
			private string url { get; set; }

			/// <summary>
			/// 文件保存路径
			/// </summary>
			private string fileUrl { get; set; }

			/// <summary>
			/// 压缩尺寸集合
			/// </summary>
			private List<SizeType> sizeList { get; set; }

			/// <summary>
			/// 构造函数
			/// </summary>
			/// <param name="url">图片路径</param>
			/// <param name="fileUrl">文件保存路径</param>
			/// <param name="sizeList">压缩尺寸<W,H></param>
			public ComPress(string url, List<SizeType> sizeList)
			{
				this.url = url;

				this.sizeList = sizeList;
			}

			/// <summary>
			/// 开始压缩
			/// </summary>
			/// <returns></returns>
			public bool Start() {
				try {

					foreach ( var size in this.sizeList ) Execute(size);

					return true;

				}
				catch(Exception e) {

					throw e;

				}
			}

			/// <summary>
			/// 执行
			/// </summary>
			public void Execute(SizeType data) {

				using ( Image originalImage = Image.FromFile(( this.url + data.imgName ).ServerPath()) )
				{
					int
						x = 0,
						y = 0,
						towidth = data.W,
						toheight = data.H,
						ow = originalImage.Width,
						oh = originalImage.Height;

					if ( ow < towidth )
					{
						originalImage.Dispose();
						return;
					}

					switch ( data.Type )
					{

						//指定高宽 - [变形]  
						case "HW":
							break;

						//指定宽 - [高按比例] 
						case "W":
							toheight = originalImage.Height * data.W / originalImage.Width;
							break;

						//指定高 - [宽按比例]
						case "H":
							towidth = originalImage.Width * data.H / originalImage.Height;
							break;

						//指定高宽 - [不变形]
						case "Cut":
							if ( originalImage.Width / (double) originalImage.Height > towidth / (double) toheight )
							{
								oh = originalImage.Height;
								ow = originalImage.Height * towidth / toheight;
								y = 0;
								x = ( originalImage.Width - ow ) / 2;
							}
							else
							{
								ow = originalImage.Width;
								oh = originalImage.Width * data.H / towidth;
								x = 0;
								y = ( originalImage.Height - oh ) / 2;
							}
							break;

						default:
							break;
					}

					//新建一个bmp图片 
					using ( Image bitmap = new Bitmap(towidth, toheight) ) {
						//新建一个画板 
						using ( Graphics g = Graphics.FromImage(bitmap) ) {

							//设置高质量插值法 
							g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

							//设置高质量,低速度呈现平滑程度 
							g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

							//清空画布并以透明背景色填充 
							g.Clear(Color.Transparent);

							//在指定位置并且按指定大小绘制原图片的指定部分 
							g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight),
								new Rectangle(x, y, ow, oh),
								GraphicsUnit.Pixel);

							try
							{

								Prototype.InsertFile(serverPath: data.filePath);

								bitmap.Save(data.fileUrl, System.Drawing.Imaging.ImageFormat.Jpeg);

							}
							catch ( Exception e )
							{
								throw e;
							}

						}
					}
				}
			}


		}

		/// <summary>
		/// 压缩类型以及尺寸
		/// </summary>
		public class SizeType
		{
			/// <summary>
			/// 宽
			/// </summary>
			public int W { get; set; }
			/// <summary>
			/// 高
			/// </summary>
			public int H { get; set; }
			/// <summary>
			/// 指定压缩类型（[HW - 指定宽高][W - 指定宽度][H - 指定高度][Cut - 指定宽高不变形]）
			/// </summary>
			public string Type { get; set; }
			/// <summary>
			/// 文件名称
			/// </summary>
			public string imgName { get; set; }
			/// <summary>
			/// 默认文件名下的生成
			/// </summary>
			public string datePath { get; set; }
			/// <summary>
			/// 文件夹路径
			/// </summary>
			public string filePath { get { return ( "/Content/ComPress/Images_" + this.W + "/" + datePath ).ServerPath(); } }
			/// <summary>
			/// 文件保存路径
			/// </summary>
			public string fileUrl { get { return ( "/Content/ComPress/Images_" + this.W + "/" + datePath + this.imgName + "" ).ServerPath(); } }
		}

		/// <summary>
		/// 压缩类型
		/// </summary>
		public enum ComPressType
		{
			/// <summary>
			/// 指定高宽 - [变形] 
			/// </summary>
			HW = 1,
			/// <summary>
			/// 指定宽 - [高按比例]
			/// </summary>
			W = 2,
			/// <summary>
			/// 指定高 - [宽按比例]
			/// </summary>
			H = 3,
			/// <summary>
			/// 指定高宽 - [不变形]
			/// </summary>
			Cut = 4
		}
	}

	/// <summary>
	/// 操作视频
	/// </summary>
	public class Vedio
	{
		/// <summary>
		/// 生成预览
		/// </summary>
		public class Preview
		{
			private string serverPath = "";

			/// <summary>
			/// 生成预览图
			/// </summary>
			/// <param name="path">视频路径</param>
			public void Img(string path,string serverPath)
			{
				this.serverPath = serverPath;
				//异步调用生成预览图
				new Task(a => { ExImg(a.ToString()); }, path).Start();
			}

			/// <summary>
			/// 执行生成视频预览图
			/// </summary>
			/// <param name="path">视频路径</param>
			private void ExImg(string path)
			{
				ProcessStartInfo startInfo = new ProcessStartInfo(serverPath + Get.AppReader("Ffmpeg").ToString());

				string
					//缩略图文件路径
					imgPath = Path.ChangeExtension(path, ".jpg"),

					//预览图文件路径
					imgSize = "600x279",

					//执行的命令行
					cmdStr = " -i " + path + " -y -f image2 -t 0.1 -s " + imgSize + " " + imgPath;

				startInfo.WindowStyle = ProcessWindowStyle.Normal;

				//startInfo.UseShellExecute = false;


				//startInfo.Arguments = "-i " + path + " -c:a copy -c:v libx264 -profile:v high -preset slower -crf:v 21 " + path + "";

				//startInfo.Arguments = "-i " + path + " -vcodec libx264 -preset fast -crf 20 -y -vf \"scale = 1920:-1\" -acodec libmp3lame -ab 128k " + path + "";

				//startInfo.Arguments = "-i \"" + path + "\" -c:a copy -c:v libx264 -vpre slow -f flv \"" + path + "\" live=1";

				//-i "2.4_mission.mp4" -vcodec libx264 -s 1920X1080 -vf "movie=stark.png [watermark]; [in][watermark] overlay=main_w-overlay_w-10:10 [out]"  -acodec copy "2.4_1080P.mp4"

				//startInfo.Arguments = "-i \"" + path + "\" -vcodec libx264 -s 1920X1080 -vf \"movie = stark.png[watermark]; [in] [watermark] overlay=main_w-overlay_w-10:10 [out]\"  -acodec copy \"" + path + "\"";

				//startInfo.Arguments = "-i " + path + " -r 10 -b:a 32k " + path;

				//startInfo.Arguments = "-i " + path + " -strict 0 -c:v libx264 -c:a aac -f hls " + path + "";

				//Process.Start(startInfo);

				startInfo.Arguments = cmdStr;

				Process.Start(startInfo);

			}
		}
	}

	/// <summary>
	/// 文件夹文件
	/// </summary>
	public class Dirctory
	{
		/// <summary>
		/// 文件夹名称集合
		/// </summary>
		private List<string> DirectoryName { get; set; }

		/// <summary>
		/// 文件路径集合
		/// </summary>
		public List<string> FilePath { get; set; }

		/// <summary>
		/// 文件路径
		/// </summary>
		private string path { get; set; }

		/// <summary>
		/// 获取文件范围 [suffix - sʌfɪks:后缀]
		/// </summary>
		private string suffix { get; set; }

		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="path">文件路径</param>
		/// <param name="suffix">后缀名</param>
		public Dirctory(string path, string suffix)
		{

			this.DirectoryName = new List<string>();

			this.FilePath = new List<string>();

			this.path = path;

			this.suffix = suffix;

			this.DirectoryName.Add(path.ServerPath());

		}

		/// <summary>
		/// 开始获取文件下所有符合条件的文件
		/// </summary>
		public void Start()
		{

			this.DirectoryList();

			foreach ( var dir in this.DirectoryName ) this.EachDirectory(dir);


		}

		/// <summary>
		/// 获取路径写所有文件夹名称[Directory - dɪ'rekt(ə)rɪ; daɪ-]
		/// </summary>
		/// <param name="path"></param>
		/// <returns></returns>
		public void DirectoryList(string path = "")
		{

			DirectoryInfo thisDirectory = null;

			if ( string.IsNullOrWhiteSpace(path) )
			{
				path = this.path;
				thisDirectory = new DirectoryInfo(path.ServerPath());
			}
			else {
				thisDirectory = new DirectoryInfo(path);
			}


			try
			{
				var subsDirectory = thisDirectory.GetDirectories();

				foreach ( var subDirectory in subsDirectory )
				{

					this.DirectoryName.Add(subDirectory.FullName);

					this.DirectoryList(subDirectory.FullName);

				}
			}
			catch {
				throw;
			}
			
		}

		/// <summary>
		/// 遍历文件夹文件
		/// </summary>
		/// <param name="path">文件夹路径</param>
		public void EachDirectory(string path)
		{

			var files = Directory.GetFiles(path,suffix,SearchOption.TopDirectoryOnly);

			foreach ( var file in files )
			{

				this.FilePath.Add(file);

			}

		}

	}

	public class Prototype
	{
		/// <summary>
		/// 创建文件夹
		/// </summary>
		/// <param name="path">文件夹地址</param>
		/// <param name="serverPath">文件夹服务器地址</param>
		/// <returns></returns>
		public static bool InsertFile(string path = "",string serverPath = "") {
			try
			{
				if ( string.IsNullOrWhiteSpace(path) )
				{
					if ( !Directory.Exists(serverPath) )
						Directory.CreateDirectory(serverPath);
				}
				else {
					if ( !Directory.Exists(path.ServerPath()) )
						Directory.CreateDirectory(path.ServerPath());
				}
				
				return true;
			}
			catch {
				return false;
			}
		}

		/// <summary>
		/// 删除文件夹
		/// </summary>
		/// <param name="path">文件夹地址</param>
		/// <param name="serverPaht">文件夹服务器地址</param>
		/// <returns></returns>
		public static bool DeleteFiles(string path = "",string serverPaht = "") {
			try
			{
				if ( string.IsNullOrWhiteSpace(path) )
					Directory.Delete(serverPaht);
				else
					Directory.Delete(serverPaht.ServerPath());
				return true;
			}
			catch {
				return false;
			}
		}

		/// <summary>
		/// 删除文件
		/// </summary>
		/// <param name="path">文件地址</param>
		/// <param name="serverPaht">文件服务器地址</param>
		/// <returns></returns>
		public static bool DeleteFile(string path = "", string serverPaht = "")
		{
			try
			{
				if ( string.IsNullOrWhiteSpace(path) )
					File.Delete(serverPaht);
				else
					File.Delete(serverPaht.ServerPath());
				return true;
			}
			catch
			{
				return false;
			}
		}

		/// <summary>
		/// 默认压缩尺寸类型
		/// </summary>
		/// <param name="imgName">文件名</param>
		/// <param name="datePath">默认文件名下的生成</param>
		/// <returns></returns>
		public static List<Img.SizeType> SizeType(string imgName,string datePath)
		{
			List<Img.SizeType> sizeTypeList = new List<Img.SizeType>();

			#region 压缩尺寸
			sizeTypeList.Add(sizeBind(120, 120, Img.ComPressType.Cut.ToString(), imgName, datePath));
			sizeTypeList.Add(sizeBind(300, 300, Img.ComPressType.Cut.ToString(), imgName, datePath));
			sizeTypeList.Add(sizeBind(500, 0, Img.ComPressType.W.ToString(), imgName, datePath));
			sizeTypeList.Add(sizeBind(800, 0, Img.ComPressType.W.ToString(), imgName, datePath));
			#endregion

			return sizeTypeList;

		}
		/// <summary>
		/// 压缩尺寸绑定
		/// </summary>
		/// <param name="w">宽</param>
		/// <param name="h">高</param>
		/// <param name="compressType">类型</param>
		/// <param name="imgName">图片名称</param>
		/// <returns></returns>
		public static Img.SizeType sizeBind(int w, int h, string compressType, string imgName,string datePath)
		{
			return new Img.SizeType() { W = w, H = h, Type = compressType, imgName = imgName,datePath = datePath };
		}
	}

}
